<?php

class Questions extends Onecore_Controller
{
    public $cfg;
    public function __construct()
    {
        parent::__construct();
        $this->load->model("objects_model");
        $this->load->model("elem_questions_model");
        $this->load->model("elem_questions_answers_model");
        $this->load->model("elem_test_model");
        $this->_moduleName = utf8_encode("Modulo modulos_model");
        $this->_moduleDescription = utf8_encode("Description") . $this->_moduleName;
        $this->_modelInstance = $this->elem_questions_model;
        $this->cfg = (object)$this->config->item("defaultCfg");
    }
    
    public function get(){
        $id = $this->input->post('id');
        $question = $this->_modelInstance->getByid($id);
        if(is_array($question)) $question = $question[0];
        if(!empty($question)){

            $question->description = str_replace("&nbsp;", ' ', $question->description);

            $answers = $this->elem_questions_answers_model->getByelem_questions_id($question->id);
            $question->answers = $answers;

            //limpiamos &quot; por ""
            for($i=0;$i<count($question->answers);$i++){
                $question->answers[$i]->description = str_replace("&nbsp;", ' ', $question->answers[$i]->description);
                $question->answers[$i]->explication = str_replace("&nbsp;", ' ', $question->answers[$i]->explication);

                $question->answers[$i]->description = html_entity_decode($question->answers[$i]->description);
                $question->answers[$i]->explication = html_entity_decode($question->answers[$i]->explication);
            }


            //si es pregunta dependiente de respuesta
            if(!empty($question->parent)){
                if($question->type_object_parent_id == $this->cfg->type_object_answer){
                    $answerParent = $this->elem_questions_answers_model->getByid($question->parent);
                    if(!empty($answerParent[0]))
                        $question->parentAnswer = $answerParent[0];
                }
            }
            if($question->type_questions_id == "2")
                $question = $this->elem_questions_answers_model->getInnerAnswersFormat($question);
            $question->description = html_entity_decode($question->description);
        }
        $res = array(
            "success" => true,
            "data" => $question
        );
        $this->layout->printLike(json_encode($res), "json");
    }   
    
    public function del(){
        $success = false;
        $itemName = $this->_modelInstance->getItemName();
        $mensaje = "Error inesperado";
        $errorList = array();
        
        $id = $this->input->post('id');
        $question = $this->_modelInstance->getByid($id);
      
        
        if(is_array($question)) $question = $question[0];
        
        if(!empty($question)){
            $data = array(
                    "id"=>$id
                );
            
            if($this->_modelInstance->del($data)){
                $mensaje = $itemName . " elimnada en forma exitosa";
                $success = true;
            }else{
                $mensaje = "La " . $itemName . " no pudo ser eliminada. Verifique los siguientes errores.";
                $errorList = array("Error" => $this->_modelInstance->getError());
            }
        }
        $data = array(
            'success' => $success,
            "msg" => $mensaje,
            "errors" => $errorList,
        );
        $this->layout->printLike(json_encode($data), "json");
    }
    public function duplicate(){
        $success = true;
        $itemName = $this->_modelInstance->getItemName();
        $mensaje = $itemName . " duplicada en forma exitosa";
        $errorList = array();
        
        $id = $this->input->post('id');
        $question = $this->_modelInstance->getByid($id);
      
        
        if(is_array($question)) $question = $question[0];
        
        if(!empty($question)){

            $answers = $this->elem_questions_answers_model->getByelem_questions_id($id);
            $question->answers = $answers;
            
            //creamos la pregunta
            $data = array(
                "id" => "",
                "data" => array(
                    'elem_test_id'=>$question->elem_test_id,
                    'description' => html_entity_decode($question->description),
                    'type_questions_id'=> $question->type_questions_id,
                )
            );
            
            $this->db->trans_begin();
            
            if ($this->_modelInstance->save($data, false)) {
                $id = $this->_modelInstance->getLastInsertedId();

                //si es respuesta seleccion multiple
                if($question->type_questions_id == "3"){
                    foreach($question->answers as $answer){
                        $answer->description = str_replace("'", "", $answer->description);
                        $answer->explication = str_replace('"', '\"', $answer->explication);
                        $data2 = array(
                            "id" => "",
                            "data" => array(
                                'value'=>(int)!empty($answer->value),
                                'description' => $answer->description,
                                'explication' => $answer->explication,
                                'elem_questions_id'=> $id,
                            )
                        );
                        if (!$this->elem_questions_answers_model->save($data2, false)) {
                            $mensaje = "La respuesta no pudo ser creada. Verifique los siguientes errores.";
                            $errorList = array("Error" => $this->elem_questions_answers_model->getError());
                            $success = false;
                            break;
                        }
                    }
                }
                else{//si es termino pareado
                    if($question->type_questions_id == "2"){
                        $question = $this->elem_questions_answers_model->getInnerAnswersFormat($question);
                        foreach($question->answers as $answer){
                            $answer->description = str_replace("'", "", $answer->description);
                            $answer->description = str_replace('"', '\"', $answer->description);
                            $data2 = array(
                                "id" => "",
                                "data" => array(
                                    'description' => $answer->description,
                                    'elem_questions_id'=> $id,
                                )
                            );
                            if (!$this->elem_questions_answers_model->save($data2, false)) {
                                $mensaje = "La respuesta del primer termino no pudo ser creada. Verifique los siguientes errores.";
                                $errorList = array("Error" => $this->elem_questions_answers_model->getError());
                                $success = false;
                                break;
                            }
                            else{
                                $parent = $this->elem_questions_answers_model->getLastInsertedId();
                                $answer->answer->description = str_replace("'", "", $answer->answer->description);
                                $answer->answer->description = str_replace('"', '\"', $answer->answer->description);

                                $data2 = array(
                                    "id" => "",
                                    "data" => array(
                                        'description' => $answer->answer->description,
                                        'elem_questions_id'=> $id,
                                        "parent"=>$parent
                                    )
                                );
                                if (!$this->elem_questions_answers_model->save($data2, false)) {
                                    $mensaje = "La respuesta del segundo termino no pudo ser creada. Verifique los siguientes errores.";
                                    $errorList = array("Error" => $this->elem_questions_answers_model->getError());
                                    $success = false;
                                    break;
                                }
                            }
                        }
                    }
                }
            } else {
                $mensaje = "La Pregunta no pudo ser creada. Verifique los siguientes errores.";
                $errorList = array("Error" => $this->_modelInstance->getError());
            }
            
            if ($success) {
                $this->db->trans_commit();
            } else {
                $this->db->trans_rollback();
            }
        }
        $data = array(
            'success' => $success,
            "msg" => $mensaje,
            "errors" => $errorList,
        );
        $this->layout->printLike(json_encode($data), "json");
    }
    public function add() {
        $this->load->library('utils');
        $cfg = $this->utils->getConfig();
        $success = true;
        $itemName = $this->_modelInstance->getItemName();
        $mensaje = $itemName . " ingresada en forma exitosa";
        $errorList = array();
        $value = 0;
        $validQuestions = false;
        $question = $this->input->post('question');
        if(!empty($question)){
            $question = json_decode($question);
        }
        
        $this->form_validation->set_rules($this->_modelInstance->getValidations());
        if ($this->form_validation->run() == FALSE) {
            $mensaje = "Campos inválidos en la pregunta";
            $errorList = $this->form_validation->_error_array;
        } else {
            $_test = $this->elem_test_model->getByid($question->elem_test_id);
            //existe test?
            if(empty($_test[0])){
                $data = array(
                    'success' => false,
                    "msg" => "Error",
                    "errors" => array("Error"=>"La prueba asociada no existe"),
                );
                $this->layout->printLike(json_encode($data), "json");
                return;
            }
            $_test =$_test[0];
            $_object = $this->objects_model->getByid($_test->objects_id);
            //existe objeto relacionado
            if(empty($_object[0])){
                $data = array(
                    'success' => false,
                    "msg" => "Error",
                    "errors" => array("Error"=>"El objetoi asociado no existe"),
                );
                $this->layout->printLike(json_encode($data), "json");
                return;
            }
            $_object = $_object[0];

            //si es caso clinico solo se aceptan preguntas Seleccion multiple
            if($_object->type_objects_id == $cfg->type_object_cliniccase){
                if($question->type_questions_id != $cfg->type_question_selection){
                    $data = array(
                        'success' => false,
                        "msg" => "Error",
                        "errors" => array("Error"=>"La prueba del Caso solo debe utilizar preguntas del tipo Selcción Múltiple"),
                    );
                    $this->layout->printLike(json_encode($data), "json");
                    return;
                }
                //vemos si ya existe una pregunta como root de arbol si es caso clinico
                $_questionsAux = $this->_modelInstance->getByelem_test_id($question->elem_test_id);
                if(empty($question->parent)){
                    if(!empty($_questionsAux)){
                        $nRoot = 0;
                        $rootquestion = array();
                        foreach ($_questionsAux as $_question) {
                            if(empty($_question->parent)){
                                $rootquestion = $_question;
                                $nRoot++;
                                break;
                            }
                        }
                        //error solo se permite un root por prueba
                        if($nRoot>0){
                            $data = array(
                                'success' => false,
                                "msg" => "Error",
                                "errors" => array("Error"=>"Para los Casos Clínicos solo puede existir una pregunta Padre sin dependencias de una respuesta, y en esta prueba esta definida por la pregunta: <br>$rootquestion->description"),
                            );
                            $this->layout->printLike(json_encode($data), "json");
                            return;
                        }
                    }
                }
            }


            if(!empty($question->value))    $value = $question->value?1:0;
            $question->description = str_replace("&nbsp;", ' ', $question->description);
            //creamos la pregunta
            $data = array(
                "id" => "",
                "data" => array(
                    'elem_test_id'=>$question->elem_test_id,
                    'description' => $question->description,
                    'value' => $value,
                    'type_questions_id'=> $question->type_questions_id,
                )
            );
            
            if(!empty($question->parent)){
                $data["data"]["parent"] = $question->parent;
                $data["data"]["type_object_parent_id"] = $question->type_object_parent_id;
            }   

            $this->db->trans_begin();
            
            if ($this->_modelInstance->save($data, false)) {
                $id = $this->_modelInstance->getLastInsertedId();
                $nTrue = 0;
                //si es respuesta seleccion multiple
                if($question->type_questions_id == "3"){
                    foreach($question->answers as $answer){
                        $answer->description = str_replace("&nbsp;", ' ', $answer->description);
                        $answer->explication = str_replace("&nbsp;", ' ', $answer->explication);
                        $data2 = array(
                            "id" => "",
                            "data" => array(
                                'value'=>(int)!empty($answer->value),
                                'description' => $answer->description,
                                'explication' => $answer->explication,
                                'elem_questions_id'=> $id,
                            )
                        );
                        if (!$this->elem_questions_answers_model->save($data2, false)) {
                            $mensaje = "La respuesta no pudo ser creada. Verifique los siguientes errores.";
                            $errorList = array("Error" => $this->elem_questions_answers_model->getError());
                            $success = false;
                            break;
                        }
                        else{
                            //si es verdadera la contamos
                            if((int)!empty($answer->value)){
                                $nTrue++;
                            }
                        }
                    }
                    //solo cuando es un objeto tema validamos que exista solo una respuesta verdadera
                    if($_object->type_objects_id == $cfg->type_object_theme){
                        if($nTrue != 1){
                            $mensaje = "La pregunta debe poseer solo una respuesta verdadera";
                            $errorList = array("Error" => "La pregunta debe poseer solo una respuesta verdadera.");
                            $success = false;
                        }    
                    }
                    
                }
                else{//si es termino pareado
                    if($question->type_questions_id == "2"){
                        foreach($question->answers as $answer){
                            $answer->description1 = str_replace("&nbsp;", ' ', $answer->description1);
                            $answer->description2 = str_replace("&nbsp;", ' ', $answer->description2);
                            $data2 = array(
                                "id" => "",
                                "data" => array(
                                    'value'=>(int)!empty($answer->value),
                                    'description' => $answer->description1,
                                    'elem_questions_id'=> $id,
                                )
                            );
                            if (!$this->elem_questions_answers_model->save($data2, false)) {
                                $mensaje = "La respuesta del primer termino no pudo ser creada. Verifique los siguientes errores.";
                                $errorList = array("Error" => $this->elem_questions_answers_model->getError());
                                $success = false;
                                break;
                            }
                            else{
                                $parent = $this->elem_questions_answers_model->getLastInsertedId();
                                $data2 = array(
                                    "id" => "",
                                    "data" => array(
                                        'value'=>(int)!empty($answer->value),
                                        'description' => $answer->description2,
                                        'elem_questions_id'=> $id,
                                        "parent"=>$parent
                                    )
                                );
                                if (!$this->elem_questions_answers_model->save($data2, false)) {
                                    $mensaje = "La respuesta del segundo termino no pudo ser creada. Verifique los siguientes errores.";
                                    $errorList = array("Error" => $this->elem_questions_answers_model->getError());
                                    $success = false;
                                    break;
                                }
                            }
                        }
                    }
                }
            } else {
                $mensaje = "La Pregunta no pudo ser creada. Verifique los siguientes errores.";
                $errorList = array("Error" => $this->_modelInstance->getError());
            }
            
            if ($success) {
                $this->db->trans_commit();
            } else {
                $this->db->trans_rollback();
            }
        }
        $data = array(
            'success' => $success,
            "msg" => $mensaje,
            "errors" => $errorList,
        );
        $this->layout->printLike(json_encode($data), "json");
    }
    public function edit() {
        $this->load->library('utils');
        $cfg = $this->utils->getConfig();

        $success = true;
        $itemName = $this->_modelInstance->getItemName();
        $mensaje = $itemName . " editada en forma exitosa";
        $errorList = array();
        
        $question = $this->input->post('question');
        
        if(!empty($question)){
            $question = json_decode($question);
        }
        //$question = $this->_modelInstance->getByid($question->id);
        if(!empty($question) ){
            
            $this->form_validation->set_rules($this->_modelInstance->getValidations());
            if ($this->form_validation->run() == FALSE) {
                $mensaje = "Campos inválidos en la pregunta";
                $errorList = $this->form_validation->_error_array;
            } else {

                $_test = $this->elem_test_model->getByid($question->elem_test_id);
                //existe test?
                if(empty($_test[0])){
                    $data = array(
                        'success' => false,
                        "msg" => "Error",
                        "errors" => array("Error"=>"La prueba asociada no existe"),
                    );
                    $this->layout->printLike(json_encode($data), "json");
                    return;
                }
                $_test =$_test[0];
                $_object = $this->objects_model->getByid($_test->objects_id);
                //existe objeto relacionado
                if(empty($_object[0])){
                    $data = array(
                        'success' => false,
                        "msg" => "Error",
                        "errors" => array("Error"=>"El objetoi asociado no existe"),
                    );
                    $this->layout->printLike(json_encode($data), "json");
                    return;
                }
                $_object = $_object[0];

                //si es caso clinico solo se aceptan preguntas Seleccion multiple
                if($_object->type_objects_id == $cfg->type_object_cliniccase){
                    if($question->type_questions_id != $cfg->type_question_selection){
                        $data = array(
                            'success' => false,
                            "msg" => "Error",
                            "errors" => array("Error"=>"La prueba del Caso solo debe utilizar preguntas del tipo Selcción Múltiple"),
                        );
                        $this->layout->printLike(json_encode($data), "json");
                        return;
                    }
                }



                $value = 0;
                if(!empty($question->value))    $value = $question->value?1:0;
                $question->description = str_replace("&nbsp;", ' ', $question->description);
                // la pregunta
                $data = array(
                    "id" => array(
                        'id'=>$question->id
                    ),
                    "data" => array(
                        'description' => $question->description,
                        'value' => $value
                    )
                );
                if(!empty($question->parent)){
                    $data["data"]["parent"] = $question->parent;
                    $data["data"]["type_object_parent_id"] = $question->type_object_parent_id;
                }   

                $nTrue  = 0;
                $this->db->trans_begin();
                
                if ($this->_modelInstance->save($data, true)) {
                    //seleccion multiple
                    if($question->type_questions_id == "3"){
                        foreach($question->answers as $answer){
                            $answer->description = str_replace("&nbsp;", ' ', $answer->description);
                            $answer->explication = str_replace("&nbsp;", ' ', $answer->explication);
                            if(!empty($answer->id)){
                                
                                $data2 = array(
                                    "id" => array(
                                        'id'=>$answer->id
                                    ),
                                    "data" => array(
                                        'value'=>(int)!empty($answer->value),
                                        'description' => $answer->description,
                                        'explication' => $answer->explication,
                                        'elem_questions_id'=> $question->id
                                    )
                                );
                                if (!$this->elem_questions_answers_model->save($data2, true)) {
                                    $mensaje = "La respuesta no pudo ser editada. Verifique los siguientes errores.";
                                    $errorList = array("Error" => $this->elem_questions_answers_model->getError());
                                    $success = false;
                                    break;
                                }
                            }
                            else{
                                //si es nueva respuesta
                                $data2 = array(
                                    "id" => "",
                                    "data" => array(
                                        'value'=>(int)!empty($answer->value),
                                        'description' => $answer->description,
                                        'elem_questions_id'=> $question->id
                                    )
                                );
                                if (!$this->elem_questions_answers_model->save($data2, false)) {
                                    $mensaje = "La respuesta no pudo ser editada. Verifique los siguientes errores.";
                                    $errorList = array("Error" => $this->elem_questions_answers_model->getError());
                                    $success = false;
                                    break;
                                }
                            }
                            if((int)!empty($answer->value)){
                                $nTrue++;
                            }
                        }
                        //solo cuando es un objeto tema validamos que exista solo una respuesta verdadera
                        if($_object->type_objects_id == $cfg->type_object_theme){
                            if($nTrue != 1){
                                $mensaje = "La pregunta debe poseer solo una respuesta verdadera";
                                $errorList = array("Error" => "La pregunta debe poseer solo una respuesta verdadera.");
                                $success = false;
                            }    
                        }
                    }
                    //terminos pareados
                    else{
                        foreach($question->answers as $answer){
                            $answer->description1 = str_replace("&nbsp;", ' ', $answer->description1);
                            $answer->description2 = str_replace("&nbsp;", ' ', $answer->description2);
                            //edicion TP
                            if(!empty($answer->id1)){
                                $data2 = array(
                                    "id" => array("id"=>$answer->id1),
                                    "data" => array(
                                        'description' => $answer->description1
                                    )
                                );
                                if (!$this->elem_questions_answers_model->save($data2, true)) {
                                    $mensaje = "La respuesta del primer termino no pudo ser creada. Verifique los siguientes errores.";
                                    $errorList = array("Error" => $this->elem_questions_answers_model->getError());
                                    $success = false;
                                    break;
                                }
                                else{
                                    $data2 = array(
                                        "id" => array("id"=>$answer->id2),
                                        "data" => array(
                                            'description' => $answer->description2
                                        )
                                    );
                                    if (!$this->elem_questions_answers_model->save($data2, true)) {
                                        $mensaje = "La respuesta del segundo termino no pudo ser creada. Verifique los siguientes errores.";
                                        $errorList = array("Error" => $this->elem_questions_answers_model->getError());
                                        $success = false;
                                        break;
                                    }
                                }
                            }
                            else{
                                $data2 = array(
                                    "id" => "",
                                    "data" => array(
                                        'description' => $answer->description1,
                                        'elem_questions_id'=> $question->id,
                                    )
                                );
                                if (!$this->elem_questions_answers_model->save($data2, false)) {
                                    $mensaje = "La respuesta del primer termino no pudo ser creada. Verifique los siguientes errores.";
                                    $errorList = array("Error" => $this->elem_questions_answers_model->getError());
                                    $success = false;
                                    break;
                                }
                                else{
                                    $parent = $this->elem_questions_answers_model->getLastInsertedId();
                                        $data2 = array(
                                        "id" => "",
                                        "data" => array(
                                            'description' => $answer->description2,
                                            'elem_questions_id'=> $question->id,
                                            "parent"=>$parent
                                        )
                                    );
                                    if (!$this->elem_questions_answers_model->save($data2, false)) {
                                        $mensaje = "La respuesta del segundo termino no pudo ser creada. Verifique los siguientes errores.";
                                        $errorList = array("Error" => $this->elem_questions_answers_model->getError());
                                        $success = false;
                                        break;
                                    }
                                }
                            }
                            
                        }
                    }
                } else {
                    $mensaje = "La Pregunta no pudo ser editada. Verifique los siguientes errores.";
                    $errorList = array("Error" => $this->_modelInstance->getError());
                }
                //vemos si elimino alguna respuesta
                if($success && !empty($question->deletedAnswers) && is_array($question->deletedAnswers) && count($question->deletedAnswers)>0){
                    foreach($question->deletedAnswers as $answerId){
                        $data = array("id"=>$answerId);
                        if(!$this->elem_questions_answers_model->del($data)){
                            $mensaje = "La " . $itemName . " no pudo ser eliminada. Verifique los siguientes errores.";
                            $errorList = array("Error" => $this->_modelInstance->getError());
                            $success = false;
                            break;
                        }
                    }
                }
                
                if ($success) {
                    $this->db->trans_commit();
                } else {
                    $this->db->trans_rollback();
                }
            }
        }
        $data = array(
            'success' => $success,
            "msg" => $mensaje,
            "errors" => $errorList,
        );
        $this->layout->printLike(json_encode($data), "json");
    }
    public function loadList(){
        $this->load->model("elem_question_types_model");
        $cfg = (object)$this->config->item("defaultCfg");
        $order = array();
        $conditions = new stdClass();
        $conditions->start = $this->input->get('start');
        $conditions->limit = $this->input->get('limit');
        $elem_test_id = $this->input->get('elem_test_id');
        $removeHTML = $this->input->get('removeHTML');
        $innerQuestions = $this->input->get('innerQuestions');
        
        $cond = array(array('type'=>'where','field'=>'elem_test_id','value'=>$elem_test_id));
        
        $order['field'] = 'index';
        $order['direction'] = 'ASC';
        
        $data = $this->_modelInstance->loadList($order,null,$cond);
        $rows = array();
        $i = 1;
        foreach($data['items'] as $question){
            $typeQuestion = $this->elem_question_types_model->getByid($question->type_questions_id);
            //tipo pregunta
            if(!empty($typeQuestion[0]))
                $question->type_questions_name = $typeQuestion[0]->name;

            $answers = $this->elem_questions_answers_model->getByelem_questions_id($question->id);
            $question->answers = $answers;
            //tratamiento especial respuesta tipo terminos pareados
            if($question->type_questions_id == 2){
                $question = $this->elem_questions_answers_model->getInnerAnswersFormat($question);
            }
            if(!empty($removeHTML) && $removeHTML == "true"){
                $question->description = html_entity_decode($question->description);
                $question->description = str_replace("<p>", "", $question->description);
                $question->description = str_replace("<em>", "", $question->description);
                $question->description = str_replace("<strong>", "", $question->description);
                $question->description = str_replace("</strong>", "", $question->description);
                $question->description = str_replace("</em>", "", $question->description);
                $question->description = str_replace("</p>", "", $question->description);
                $question->description = str_replace("&nbsp;", "", $question->description);
                $question->description = preg_replace("/&#?[a-z0-9]+;/i","",$question->description);
                $question->description = $i.".- ".$question->description;
                $i++;
            }
            else{
                $question->description = str_replace("&nbsp;", ' ', $question->description);
                $question->description = html_entity_decode($question->description);
            }
                

            //ha sido mirado por el algoritmo
            $question->looked = false;
            //profundidad
            $question->deep = 0;
            //indice tipo 1, 1.1, 1.2, 1.2.1, etc
            $question->indexname = "1";

            $rows[] = $question;
        }

        $tree = array();

        if($innerQuestions == "true"){
            $this->_modelInstance->_questions = $rows;
            $tree = $this->_modelInstance->getTree();
            $rows = $this->_modelInstance->_questionsList;
            //print_r
        }

        
        $res = array(
            "success" => true,
            "results" => $data['results'],
            "rows" => $rows,
            "tree" => $tree
        );
        $this->layout->printLike(json_encode($res), "json");
    }   

    public function next(){
        $this->load->library('utils');
        $this->load->model("users_exec_model");
        $this->load->model("modules_model");
        $this->load->model("modules_objects_model");
        $this->load->model("elem_test_model");
        $this->load->model("role_group_model");

        $cfg = $this->utils->getConfig();
        $uid = $this->session->userdata('id_usuario');
        $userEmail = $this->session->userdata('uid');

        $qCurrentId = $this->input->post('qCurrentId');
        $elem_test_id = $this->input->post('elem_test_id');
        $answerId = $this->input->post('answerId');
        $putHit = $this->input->post('putHit');
        //$isCache = !empty($this->input->post('isCache'));

        $question = $this->_modelInstance->getByid($qCurrentId);
        $next = new stdClass();
        $questions = array();
        $next = new stdClass();
        $lastQuestion = new stdClass();
        $lastQuestions = array();
        $testQuestions = array();

        if(empty($qCurrentId)){
            $res = array(
                "success" => false,
                "message"=> "Identificador de pregunta invalido",
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }
        if(empty($elem_test_id)){
            $res = array(
                "success" => false,
                "message"=> "Identificador de prueba invalido",
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }
        if(empty($question[0])){
            log_message("warn","(next) Question no existe en BD [$qCurrentId]");
            $res = array(
                "success" => false,
                "message"=> "Pregunta [$qCurrentId] no existe",
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }

        $question = $question[0];

        //obtenemos configuracion de objeto
        $options = new stdClass();
        $options->users_id = $uid;
        $options->id = $elem_test_id;
        $configObject = $this->elem_test_model->getConfig($options);

        //obtenemos configuracion de ejecucion de prueba del alumno
        $query = new stdClass();
        $query->users_id = $uid;
        $query->objects_id = $elem_test_id;
        $query->objectversion = $configObject->version;
        $query->type_objects_id = $cfg->type_object_test;
        $lastTest = $this->users_exec_model->lastHit($query);
        if($lastTest ==null){
            log_message("warn","(next) No existe historial ejecucion en BD para test [$elem_test_id]");
            $res = array(
                "success" => false,
                "message"=> "No existe historial ejecucion en BD para test [$elem_test_id]",
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }

        $lastTest->execdetail = str_replace("&quot;", '"', $lastTest->execdetail);
        $lastTest->execdetail = json_decode($lastTest->execdetail);

        if(empty($lastTest->execdetail->questions)){
            $res = array(
                "success" => false,
                "message"=> "Prueba mal configurada. No posee definicion de preguntas a utilizar",
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }

        $testQuestions =  $lastTest->execdetail->questions;
        //si es caso clinico debemos traer preguntas asociadas a la respuesta que seleeciono
        if($configObject->type_objects_id == $cfg->type_object_cliniccase){
            $options = new stdClass();
            $options->type_object_parent_id = $cfg->type_object_answer;
            $options->parent = $answerId;
            $questions = $this->_modelInstance->getInnerQuestionsByParent($options);

            if(empty($questions[0])){
                $res = array(
                    "success" => false,
                    "message"=> "No existen mas preguntas asociadas a esta resouesta.",
                    "data" => null
                );
                $this->layout->printLike(json_encode($res), "json");
                return;
            }
            $next = $questions[0];
        }
        else{
            //si es tema
            if($configObject->type_objects_id == $cfg->type_object_theme){
                $config = json_decode($configObject->config);
                //validamos que no sea la ultima pregunta del test
                if($qCurrentId == $testQuestions[count($testQuestions)-1]){
                    $res = array(
                        "success" => false,
                        "message"=> "No existen mas preguntas configuradas para la prueba.",
                        "data" => null
                    );
                    $this->layout->printLike(json_encode($res), "json");
                    return;
                }

                /*
                //vemos si la pregunta actual a sido contestada correctamente
                $query = new stdClass();
                $query->users_id = $uid;
                $query->objects_id = $question->id;
                $query->objectversion = $configObject->version;
                $query->type_objects_id = $cfg->type_object_question;
                $lastHit = $this->users_exec_model->lastHit($query);
                
                
                //si no ha sido contestada con exito 
                if($lastHit == null || $lastHit->status == $cfg->object_user_exec){
                    $res = array(
                        "success" => false,
                        "message"=> "La pregunta no ha sido contestada exitosamente para continuar con la siguiente",
                        "data" => null
                    );
                    $this->layout->printLike(json_encode($res), "json");
                    return;
                }
                */

                //buscamos indice pregunta actual
                $index = array_search($qCurrentId, $testQuestions);
                //existe siguiente indice?
                if(empty($testQuestions[$index+1])){
                    log_message("error","(next) Error al consultar indice [$index] en arreglo de preguntas ".json_encode($testQuestions));
                    $res = array(
                        "success" => false,
                        "message"=> "No existen mas preguntas configuradas para la prueba.",
                        "data" => null
                    );
                    $this->layout->printLike(json_encode($res), "json");
                    return;
                }
                
                $nextID = $testQuestions[$index+1];
                $next = $this->_modelInstance->getByid($nextID);
                if(empty($next[0])){
                    log_message("error","(next) Pregunta [$next->id] obtenida segun arreglo de preguntas en config de modulo no existe");
                    $res = array(
                        "success" => false,
                        "message"=> "La pregunta  siguiente no existe.",
                        "data" => null
                    );
                    $this->layout->printLike(json_encode($res), "json");
                    return;
                }

                $next = $next[0];
                $next->isCache = false;
                $next->WTF = false;

                //vemos si esta pregunta ya ha sido respòndida para incluir su historial de ejecucion
                $query = new stdClass();
                //$query->users_id = $uid;
                $query->objects = $next->id;
                $query->type_objects_id = $cfg->type_object_question;
                $query->dcreated = $lastTest->dcreated;
                $query->objectversion = $configObject->version;
                $lastQuestion = $this->users_exec_model->getExecutedObjects($query);

                if(!empty($lastQuestion[0])){
                    $next->isCache = true;
                    $next->WTF = true;
                    $lastQuestion = $lastQuestion[0];
                    //pregunta seleccion multiple
                    if($next->type_questions_id == $cfg->type_question_selection || $next->type_questions_id == $cfg->type_question_truefalse){
                        $lastQuestion->execdetail = str_replace("&quot;", '"', $lastQuestion->execdetail);
                        $lastQuestion->execdetail = json_decode($lastQuestion->execdetail);
                    }
                    else{
                        //terminos pareados
                        if($next->type_questions_id == $cfg->type_question_pairterms){
                            $next->answers = $this->elem_questions_answers_model->getByelem_questions_id($next->id);
                            $answersList = array();
                            $aux = array();
                            foreach($next->answers as $ans){
                                if($ans->parent == "0"){
                                    $aux[] = $ans;
                                    $answersList[] = $ans->id;
                                }
                            }
                            $next->answers = $aux;

                            $query = new stdClass();
                            $query->users_id = $uid;
                            $query->objects = $answersList;
                            $query->objectversion = $configObject->version;
                            $query->type_objects_id = $cfg->type_object_answer;
                            $query->dcreated = $lastTest->dcreated;
                            $query->direction = "ASC";

                            $execAnswers = $this->users_exec_model->getExecutedObjects($query);

                            foreach($execAnswers as $exec){
                                $exec->execdetail = str_replace("&quot;", '"', $exec->execdetail);
                                $exec->execdetail = json_decode($exec->execdetail);
                                $lastQuestions[$exec->objects_id] = $exec;
                            }
                            $lastQuestions = array_values($lastQuestions);
                        }
                    }
                }
            }                
        }
        
        $next->answers = $this->elem_questions_answers_model->getByelem_questions_id($next->id);
        if($next->type_questions_id == $cfg->type_question_pairterms){
            $next = $this->elem_questions_answers_model->getInnerAnswersFormat($next);
        }
        
        $next->description = html_entity_decode($next->description);
        
        if($configObject->type_objects_id == $cfg->type_object_theme){
            if(!empty($next->answers))
                shuffle($next->answers);    
            $lastQuestion = null;
            $lastQuestions = null;
        }

        $res = array(
            "success" => true,
            "data" => $next,
            "selected" => $lastQuestion,
            "selecteds" => $lastQuestions,
        );
        $this->layout->printLike(json_encode($res), "json");
    }
/*

    public function next_20140216(){
        $this->load->library('utils');
        $this->load->model("users_exec_model");
        $this->load->model("modules_model");
        $this->load->model("modules_objects_model");
        $this->load->model("elem_test_model");
        $this->load->model("role_group_model");

        $cfg = $this->utils->getConfig();
        $uid = $this->session->userdata('id_usuario');
        $userEmail = $this->session->userdata('uid');

        $qCurrentId = $this->input->post('qCurrentId');
        $elem_test_id = $this->input->post('elem_test_id');
        $answerId = $this->input->post('answerId');
        $putHit = $this->input->post('putHit');

        $question = $this->_modelInstance->getByid($qCurrentId);
        $next = new stdClass();
        $questions = array();

        if(empty($answerId) && $putHit == "true"){
            $res = array(
                "success" => false,
                "errors"=> array("Debe seleccionar una respuesta válida"),
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }
        if(empty($qCurrentId)){
            $res = array(
                "success" => false,
                "errors"=> array("Identificador de pregunta invalido"),
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }
        if(empty($elem_test_id)){
            $res = array(
                "success" => false,
                "errors"=> array("Identificador de prueba invalido"),
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }
        if(empty($question[0])){
            log_message("warn","(next) Question no existe en BD [$qCurrentId]");
            $res = array(
                "success" => false,
                "errors"=> array("Pregunta [$qCurrentId] no existe"),
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }

        $current = $question[0];

        //obtenemos configuracion de objeto
        $options = new stdClass();
        $options->users_id = $uid;
        $options->id = $elem_test_id;
        $configObject = $this->elem_test_model->getConfig($options);

        $next = new stdClass();
        $lastQuestion = new stdClass();
        $lastQuestions = array();
        //si es caso clinico debemos traer preguntas asociadas a la respuesta que seleeciono
        if($configObject->type_objects_id == $cfg->type_object_cliniccase){
            $options = new stdClass();
            $options->type_object_parent_id = $cfg->type_object_answer;
            $options->parent = $answerId;
            $questions = $this->_modelInstance->getInnerQuestionsByParent($options);
            $next = $questions[0];
        }
        else{
            //si es tema
            if($configObject->type_objects_id == $cfg->type_object_theme){
                $config = json_decode($configObject->config);
                //obtenemos configuracion de ejecucion de prueba del alumno
                $query = new stdClass();
                $query->users_id = $uid;
                $query->objects_id = $elem_test_id;
                $query->objectversion = $configObject->version;
                $query->type_objects_id = $cfg->type_object_test;
                $lastTest = $this->users_exec_model->lastHit($query);
                if($lastTest!=null){
                    $lastTest->execdetail = str_replace("&quot;", '"', $lastTest->execdetail);
                    $lastTest->execdetail = json_decode($lastTest->execdetail);
                    //si aun es posible ejecutar el test
                    if($lastTest->status == "EXEC"){
                        if($putHit == "true"){
                            //obtenemos todas las preguntas que ya han sido ejecutadas
                            $query->type_objects_id = $cfg->type_object_test;
                            $query->dcreated = $lastTest->dcreated;
                            $query->questions = $lastTest->execdetail->questions;
                            $query->type_objects_id = $cfg->type_object_question;
                            $execQuestions = $this->users_exec_model->getLastExecutedQuestions($query);
                            if(!empty($execQuestions) && count($execQuestions)>0){
                                //validamos si la ultima pregunta fue contestada en forma correcta
                                if( $execQuestions[0]->status == "OK" ){
                                    //filtramops todas las respondidas correctamente 
                                    $auxExecQ = array();
                                    foreach($execQuestions as $execQuestion){
                                        if($execQuestion->status == "OK")
                                            $auxExecQ[$execQuestion->objects_id] = $execQuestion;
                                    }

                                    //log_message("error","count exec: ".count($auxExecQ).", count config: ".count($lastTest->execdetail->questions));

                                    if(count($auxExecQ) < count($lastTest->execdetail->questions)){
                                        $nextID = $lastTest->execdetail->questions[count($auxExecQ)];
                                        $next = $this->_modelInstance->getByid($nextID);
                                        $next = $next[0];
                                    }
                                    else{
//                                        log_message("error","preguntas: ".json_encode($auxExecQ));
                                        $res = array(
                                            "success" => false,
                                            "message"=>"No existen mas preguntas por responder.",
                                            "data" => ""
                                        );
                                        $this->layout->printLike(json_encode($res), "json");
                                        return;
                                    }
                                }
                                else{
                                    $res = array(
                                        "success" => false,
                                        "message"=>"No se puede cargar pregunta siguiente si no se ha contestado la actual en forma correcta",
                                        "data" => ""
                                    );
                                    $this->layout->printLike(json_encode($res), "json");
                                    return;
                                }
                            }
                            else{
                                $res = array(
                                    "success" => false,
                                    "message"=>"Primero debe responder para seguir con la siguiente pregunta",
                                    "data" => ""
                                );
                                $this->layout->printLike(json_encode($res), "json");
                                return;
                            }
                        }
                        else{
                            $i=0;
                            foreach($lastTest->execdetail->questions as $id){
                                if($id == $qCurrentId){
                                    break;
                                }
                                $i++;
                            }
                            if(!empty($lastTest->execdetail->questions[$i+1])){
                                $nextID = $lastTest->execdetail->questions[$i+1];
                                $next = $this->_modelInstance->getByid($nextID);
                                $next = $next[0];  

                                //pregunta seleccion multiple
                                if($next->type_questions_id == $cfg->type_question_selection){
                                    //obtenemos la respuesta seleccionada por le usuario
                                    $query = new stdClass();
                                    $query->users_id = $uid;
                                    $query->objects_id = $next->id;
                                    $query->objectversion = $configObject->version;
                                    $query->type_objects_id = $cfg->type_object_question;

                                    //log_message("error","query last hit pregunta: ".json_encode($query));

                                    $lastQuestion = $this->users_exec_model->lastHit($query);
                                    if($lastQuestion){
                                        $lastQuestion->execdetail = str_replace("&quot;", '"', $lastQuestion->execdetail);
                                        $lastQuestion->execdetail = json_decode($lastQuestion->execdetail);    
                                    }
                                }
                                else{
                                    //terminos pareados
                                    if($next->type_questions_id == $cfg->type_question_pairterms){
                                        $next->answers = $this->elem_questions_answers_model->getByelem_questions_id($next->id);
                                        $answersList = array();
                                        $aux = array();
                                        foreach($next->answers as $ans){
                                            if($ans->parent == "0"){
                                                $aux[] = $ans;
                                                $answersList[] = $ans->id;
                                            }
                                        }
                                        $next->answers = $aux;

                                        $query = new stdClass();
                                        $query->users_id = $uid;
                                        $query->objects = $answersList;
                                        $query->objectversion = $configObject->version;
                                        $query->type_objects_id = $cfg->type_object_answer;
                                        $query->dcreated = $lastTest->dcreated;
                                        $query->direction = "ASC";

                                        $execAnswers = $this->users_exec_model->getExecutedObjects($query);

                                        foreach($execAnswers as $exec){
                                            $exec->execdetail = str_replace("&quot;", '"', $exec->execdetail);
                                            $exec->execdetail = json_decode($exec->execdetail);
                                            $lastQuestions[$exec->objects_id] = $exec;
                                        }
                                        $lastQuestions = array_values($lastQuestions);
                                    }
                                }
                            }
                        }
                    }
                    else{
                        if($putHit == "false"){
                            $i=0;
                            foreach($lastTest->execdetail->questions as $id){
                                if($id == $qCurrentId){
                                    break;
                                }
                                $i++;
                            }
                            if(!empty($lastTest->execdetail->questions[$i+1])){
                                $nextID = $lastTest->execdetail->questions[$i+1];
                                $next = $this->_modelInstance->getByid($nextID);
                                $next = $next[0];  

                                //obtenemos la respuesta seleccionada por le usuario
                                $query = new stdClass();
                                $query->users_id = $uid;
                                $query->objects_id = $next->id;
                                $query->objectversion = $configObject->version;
                                $query->type_objects_id = $cfg->type_object_question;

                                //log_message("error","query last hit pregunta: ".json_encode($query));

                                $lastQuestion = $this->users_exec_model->lastHit($query);
                                if($lastQuestion){
                                    $lastQuestion->execdetail = str_replace("&quot;", '"', $lastQuestion->execdetail);
                                    $lastQuestion->execdetail = json_decode($lastQuestion->execdetail);    
                                }
                            }
                        }
                        else{
                            //test finalizado
                            if($lastTest->status == $cfg->object_user_approved){
                                $res = array(
                                    "success" => false,
                                    "message"=>"El test se encuentra aprobado, ya se han contestado todas las preguntas en forma correcta",
                                    "data" => ""
                                );
                                $this->layout->printLike(json_encode($res), "json");
                                return;
                            }    
                        }
                                                
                    }
                }
                else{
                    log_message("error","(next) No existe configuracion de ejecucion [users_exec_objects] para la prueba [$elem_test_id]");
                }
            }                
        }
        
        $next->answers = $this->elem_questions_answers_model->getByelem_questions_id($next->id);
        if($next->type_questions_id == $cfg->type_question_pairterms){
            $next = $this->elem_questions_answers_model->getInnerAnswersFormat($next);
        }
        
        $next->description = html_entity_decode($next->description);

        if($configObject->type_objects_id == $cfg->type_object_theme){
            shuffle($prev->answers);    
            $lastQuestion = null;
            $lastQuestions = null;
        }

        $res = array(
            "success" => true,
            "data" => $next,
            "selected" => $lastQuestion,
            "selecteds" => $lastQuestions,
        );
        $this->layout->printLike(json_encode($res), "json");
    }
    */
    public function prev(){
        $this->load->library('utils');
        $this->load->model("users_exec_model");
        $this->load->model("modules_model");
        $this->load->model("modules_objects_model");
        $this->load->model("elem_test_model");
        $this->load->model("role_group_model");

        $cfg = $this->utils->getConfig();
        $uid = $this->session->userdata('id_usuario');
        $userEmail = $this->session->userdata('uid');

        $qCurrentId = $this->input->post('qCurrentId');
        $elem_test_id = $this->input->post('elem_test_id');

        $question = $this->_modelInstance->getByid($qCurrentId);
        $next = new stdClass();
        $questions = array();


        
        if(empty($qCurrentId)){
            $res = array(
                "success" => false,
                "message"=> "Identificador de pregunta invalido",
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }
        if(empty($elem_test_id)){
            $res = array(
                "success" => false,
                "message"=> "Identificador de prueba invalido",
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }
        if(empty($question[0])){
            log_message("warn","(next) Question no existe en BD [$qCurrentId]");
            $res = array(
                "success" => false,
                "message"=> "Pregunta [$qCurrentId] no existe",
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }

        

        $current = $question[0];
        $question = $question[0];

        //obtenemos configuracion de objeto
        $options = new stdClass();
        $options->users_id = $uid;
        $options->id = $elem_test_id;
        $configObject = $this->elem_test_model->getConfig($options);

        //obtenemos configuracion de ejecucion de prueba del alumno
        $query = new stdClass();
        $query->users_id = $uid;
        $query->objects_id = $elem_test_id;
        $query->objectversion = $configObject->version;
        $query->type_objects_id = $cfg->type_object_test;
        $lastTest = $this->users_exec_model->lastHit($query);
        if($lastTest ==null){
            log_message("warn","(next) No existe historial ejecucion en BD para test [$elem_test_id]");
            $res = array(
                "success" => false,
                "message"=> "No existe historial ejecucion en BD para test [$elem_test_id]",
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }
        $lastTest->execdetail = str_replace("&quot;", '"', $lastTest->execdetail);
        $lastTest->execdetail = json_decode($lastTest->execdetail);

        $prev = new stdClass();
        $lastQuestion = new stdClass();
        $lastQuestions = array();

        $prev->isCache = false;
        $prev->WTF = false;

        //si es caso clinico debemos traer preguntas asociadas a la respuesta que seleeciono
        if($configObject->type_objects_id == $cfg->type_object_cliniccase){
            $parentAnswer = $this->elem_questions_answers_model->getByid($question->parent);
            
            if(empty($parentAnswer[0])){

                log_message("error","No existen la respuesta padre asociada a esta pregunta [$question->id] dependiente");

                $res = array(
                    "success" => false,
                    "message"=> "No existen la respuesta padre asociada a esta pregunta dependiente",
                    "data" => null
                );
                $this->layout->printLike(json_encode($res), "json");
                return;
            }

            $parentAnswer = $parentAnswer[0];
            //de la respuesta obtenemos la pregunta anterior
            $prev = $this->_modelInstance->getByid($parentAnswer->elem_questions_id);
            if(empty($prev[0])){

                log_message("error","No existen la pregunta id [$parentAnswer->elem_questions_id] de la respuesta [$parentAnswer->id] dependiente");

                $res = array(
                    "success" => false,
                    "message"=> "No existe la pregunta asociada a la respuesta seleccionada",
                    "data" => null
                );
                $this->layout->printLike(json_encode($res), "json");
                return;
            }
            $prev = $prev[0];
        }
        else{
            //si es tema
            if($configObject->type_objects_id == $cfg->type_object_theme){
                $config = json_decode($configObject->config);
                $index = array_search($qCurrentId, $lastTest->execdetail->questions);
                if($index-1 >= 0){
                    
                    $prevID = $lastTest->execdetail->questions[$index-1];
                    $prev = $this->_modelInstance->getByid($prevID);

                    if(empty($prev[0])){
                        log_message("warn","(prev) Respuesta [$prevID] no existe en BD segun configuracion de ejecucion");
                        $res = array(
                            "success" => false,
                            "message"=> "Respuesta [$prevID] no existe",
                            "data" => null
                        );
                        $this->layout->printLike(json_encode($res), "json");
                        return;
                    }

                    $prev = $prev[0];  


                    //obtenemos la respuesta seleccionada por le usuario
                    $query = new stdClass();
                    $query->users_id = $uid;
                    $query->objects = $prev->id;
                    $query->type_objects_id = $cfg->type_object_question;
                    $query->dcreated = $lastTest->dcreated;
                    $query->objectversion = $configObject->version;
                    $lastQuestion = $this->users_exec_model->getExecutedObjects($query);
                    if(!empty($lastQuestion[0])){
                        $lastQuestion = $lastQuestion[0];
                        $prev->isCache = true;
                        $prev->WTF = true;
                        if($prev->type_questions_id == $cfg->type_question_selection || $prev->type_questions_id == $cfg->type_question_truefalse){
                            $lastQuestion->execdetail = str_replace("&quot;", '"', $lastQuestion->execdetail);
                            $lastQuestion->execdetail = json_decode($lastQuestion->execdetail);
                        }
                        else{
                            if($prev->type_questions_id == $cfg->type_question_pairterms){
                                //obtenemos las respuestas padre 
                                $prev->answers = $this->elem_questions_answers_model->getByelem_questions_id($prev->id);
                                $answersList = array();
                                $aux = array();
                                foreach($prev->answers as $ans){
                                    if($ans->parent == "0"){
                                        $aux[] = $ans;
                                        $answersList[] = $ans->id;
                                    }
                                }
                                $prev->answers = $aux;

                                $query = new stdClass();
                                $query->users_id = $uid;
                                $query->objects = $answersList;
                                $query->objectversion = $configObject->version;
                                $query->type_objects_id = $cfg->type_object_answer;
                                $query->dcreated = $lastTest->dcreated;
                                $query->direction = "ASC";

                                $execAnswers = $this->users_exec_model->getExecutedObjects($query);

                                foreach($execAnswers as $exec){
                                    $exec->execdetail = str_replace("&quot;", '"', $exec->execdetail);
                                    $exec->execdetail = json_decode($exec->execdetail);
                                    $lastQuestions[$exec->objects_id] = $exec;
                                }
                                $lastQuestions = array_values($lastQuestions);
                            }
                        }
                    }
                }
                else{
                    $res = array(
                        "success" => false,
                        "message"=>"No hay preguntas previas",
                        "data" => ""
                    );
                    $this->layout->printLike(json_encode($res), "json");
                    return;
                }   
                
            }                
        }
        
        $prev->answers = $this->elem_questions_answers_model->getByelem_questions_id($prev->id);
        if($prev->type_questions_id == $cfg->type_question_pairterms){
            $prev = $this->elem_questions_answers_model->getInnerAnswersFormat($prev);
        }
        
        $prev->description = html_entity_decode($prev->description);


        if($configObject->type_objects_id == $cfg->type_object_theme){
            if(!empty($next->answers))
                shuffle($next->answers);    
            $lastQuestion = null;
            $lastQuestions = null;
        }
        

        $res = array(
            "success" => true,
            "selected"=>$lastQuestion,
            "selecteds"=>$lastQuestions,
            "data" => $prev
        );
        $this->layout->printLike(json_encode($res), "json");
    }
    public function reply(){
        $this->load->library('utils');
        $this->load->model("users_exec_model");
        $this->load->model("modules_model");
        $this->load->model("modules_objects_model");
        $this->load->model("elem_test_model");
        $this->load->model("role_group_model");

        $cfg = $this->utils->getConfig();

        $uid = $this->session->userdata('id_usuario');
        $groups_id = $this->session->userdata('groups_id');
        $userEmail = $this->session->userdata('uid');

        $qCurrentId = $this->input->post('qCurrentId');
        $elem_test_id = $this->input->post('elem_test_id');
        $answerId = $this->input->post('answerId');
        $answerInnerId = $this->input->post('answerInnerId');

        $question = $this->_modelInstance->getByid($qCurrentId);
        $next = new stdClass();
        $questions = array();
        $correct = false;
        $reset = false;
        $disableTest = false;
        $newFirstQuestion = array();

        if(empty($qCurrentId)){
            $res = array(
                "success" => false,
                "errors"=> array("Identificador de pregunta invalido"),
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }
        if(empty($elem_test_id)){
            $res = array(
                "success" => false,
                "errors"=> array("Identificador de prueba invalido"),
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }
        if(empty($question[0])){
            log_message("warn","(next) Question no existe en BD [$qCurrentId]");
            $res = array(
                "success" => false,
                "errors"=> array("Pregunta [$qCurrentId] no existe"),
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }
        
        $current = $question[0];
        $question = $question[0];

        if(empty($answerId) && $question->type_questions_id != $cfg->type_question_truefalse){
            $res = array(
                "success" => false,
                "message"=> "Debe seleccionar una respuesta válida",
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }
        //si es termino pareado, validamos que haya seleccionado la respuesta inner
        if($question->type_questions_id == $cfg->type_question_pairterms 
            && empty($answerInnerId)){
            $res = array(
                "success" => false,
                "errors"=> array("Debe seleccionar una opción del termino derecho válido"),
                "data" => null
            );
            $this->layout->printLike(json_encode($res), "json");
            exit;
        }

        //obtenemos configuracion de objeto tema/caso
        $options = new stdClass();
        $options->users_id = $uid;
        $options->id = $elem_test_id;
        $configObject = $this->elem_test_model->getConfig($options);

        $_pairTermsAnswers = array();

        //obtenemos hit de test con configuracion y estados
        $query = new stdClass();
        $query->users_id = $uid;
        $query->objects_id = $elem_test_id;
        $query->objectversion = $configObject->version;
        $query->type_objects_id = $cfg->type_object_test;
        $lastTest = $this->users_exec_model->lastHit($query);
        $lastTest->execdetail = str_replace("&quot;", '"', $lastTest->execdetail);
        $lastTest->execdetail = json_decode($lastTest->execdetail);   


        //solo cuando es tema restringimos el seguir respondiendo la prueba
        if($configObject->type_objects_id == $cfg->type_object_theme){
            if($lastTest->status == $cfg->object_user_approved){
                $res = array(
                    "success" => false,
                    "message" => "La prueba ya se encuentra finalizada. No se puede seguir contestando"
                );
                $this->layout->printLike(json_encode($res), "json");
                return;
            }
        }

        //obtenemos ultimo HIT de objeto y lo actualizamos
        $query = new stdClass();
        $query->users_id = $uid;
        $query->objects_id = $configObject->id;
        $query->objectversion = $configObject->version;
        $query->type_objects_id = $configObject->type_objects_id;
        $lastExec = $this->users_exec_model->lastHit($query);
        if($lastExec==null){
            $res = array(
                "success" => false,
                "message" => "El objeto Caso [$configObject->id] no posee historial de ejecucion inicial"
            );
            $this->layout->printLike(json_encode($res), "json");
            return;
        }

        $right = $this->elem_questions_answers_model->getRightAnswer($current->id);
        $rightId = 0;
        if($right==null){
            log_message("error","(reply) Pregunta [$current->id] no posee respuesta verdadera con value=[1]");
        }
        else{
            $rightId = $right->id;
        }

        $hit = new stdClass();
        $correct = true;
        //si es una pregunta de seeleccion multiple
        if($question->type_questions_id == $cfg->type_question_selection){
            //obtenemos respuesta
            $answered = $this->elem_questions_answers_model->getByid($answerId);
            if(empty($answered[0])){
                $res = array(
                    "success" => false,
                    "message" => "La respuesta seleccionada no existe"
                );
                $this->layout->printLike(json_encode($res), "json");
                log_message("error","(reply) Respuesta contestada id [$answerId] no existe en BD");

                return;
            }
            $answered = $answered[0];

            //hit de pregunta respondida
            $hit->users_id = $uid;
            $hit->objects_id = $current->id;
            $hit->type_objects_id = $cfg->type_object_question;
            $hit->status = "OK";
            $hit->objectversion = $configObject->version;
            $hit->execdetail = json_encode(array("selected"=>$answerId,"right"=>$rightId));
            if($answered->value == "0"){
                $correct = false;
                $hit->status = "EXEC";
            }

            if(!$this->users_exec_model->hit($hit)){
                $error = $this->users_exec_model->getError();
                log_message("error","(next) No se pudo registrar hit users_id=[$uid], 
                                                    object_id=[$hit->objects_id], 
                                                    type_objects_id=[$hit->type_objects_id]. 
                                                    Detalle=[$error]");
            }
            /*
            if($answerId != $rightId)
                $hit->status = "EXEC";
            if(!$this->users_exec_model->hit($hit)){
                $error = $this->users_exec_model->getError();
                log_message("error","(next) No se pudo registrar hit users_id=[$uid], 
                                                    object_id=[$hit->objects_id], 
                                                    type_objects_id=[$hit->type_objects_id]. 
                                                    Detalle=[$error]");
            }
            */
        }
        else{
            //terminos pareados
            if($question->type_questions_id == $cfg->type_question_pairterms){
                //obtenemos respuesta dependiente seleccionada
                $innerSelected = $this->elem_questions_answers_model->getByid($answerInnerId);
                if(!empty($innerSelected[0])){
                    $innerSelected = $innerSelected[0];
                    //obtenemos respuesta dependiente configurada como verdadera
                    $innerRight = $this->elem_questions_answers_model->getByparent($answerId);
                    if(!empty($innerRight[0])){
                        $innerRight = $innerRight[0];
                        //hit de pregunta 
                        $hit->users_id = $uid;
                        $hit->objects_id = $answerId;
                        $hit->type_objects_id = $cfg->type_object_answer;
                        $hit->status = "OK";
                        $hit->objectversion = $configObject->version;

                        $hit->execdetail = json_encode(array(
                            "selected"=>$answerInnerId,
                            "right"=>$innerRight->id
                        ));
                        $correct = true;
                        //si la seleccionada como inner es distinta a ala configurada 
                        if($innerSelected->parent != $answerId){
                            $hit->status = "EXEC";
                            $correct = false;
                        }
                        if(!$this->users_exec_model->hit($hit)){
                            $error = $this->users_exec_model->getError();
                            log_message("error","(reply) No se pudo registrar hit users_id=[$uid], 
                                                        object_id=[$hit->objects_id], 
                                                        type_objects_id=[$hit->type_objects_id], 
                                                        status=[$hit->status],
                                                        Detalle=[$error]");
                        }
                        //consultamos si el numero de respuestas OK es igual al numero de respuestas de la pregunta
                        //a partir de la ultima ejecucion de la prueba
                        $question->answers = $this->elem_questions_answers_model->getByelem_questions_id($question->id);
                        $answersList = array();
                        foreach($question->answers as $answer){
                            //solo respuestas parent
                            if($answer->parent == "0")
                                $answersList[] = $answer->id;
                        }



                        $query = new stdClass();
                        $query->users_id = $uid;
                        $query->objects = $answersList;
                        $query->objectversion = $configObject->version;
                        $query->type_objects_id = $cfg->type_object_answer;
                        $query->dcreated = $lastTest->dcreated;
                        $execAnswers = $this->users_exec_model->getExecutedObjects($query);

                        $_pairTermsAnswers = $execAnswers;

                        if(!empty($execAnswers)){
                            $okAnswers = array();
                            $totalExec = array();
                            foreach($execAnswers as $exec){
                                if($exec->status == "OK"){
                                    $okAnswers[$exec->objects_id] = $exec;
                                }
                                else{
                                    $totalExec[$exec->objects_id] = $exec;
                                }
                            }
                            //si la cantidad de respuestas correctas es igual a la configurada, 
                            //la pregunta completa se rtegistra como correcta
                            if(count($okAnswers) == count($answersList)){

                                $hit = new stdClass();
                                $hit->users_id = $uid;
                                $hit->objects_id = $question->id;
                                $hit->type_objects_id = $cfg->type_object_question;
                                $hit->status = "OK";
                                $hit->objectversion = $configObject->version;
                                if(!$this->users_exec_model->hit($hit)){
                                    $error = $this->users_exec_model->getError();
                                    log_message("error","(next) No se pudo registrar hit users_id=[$uid], 
                                                                        object_id=[$hit->objects_id], 
                                                                        type_objects_id=[$hit->type_objects_id]. 
                                                                        Detalle=[$error]");
                                }

                                $hitStatus = $hit->status ;
                            }
                            else{
                                //si ha contestado todo pero no ha sido correcto el  100% registramos un fallo
                                if(count($totalExec) == count($answersList)){
                                    $hit = new stdClass();
                                    $hit->users_id = $uid;
                                    $hit->objects_id = $question->id;
                                    $hit->type_objects_id = $cfg->type_object_question;
                                    $hit->status = "EXEC";
                                    $hit->objectversion = $configObject->version;
                                    if(!$this->users_exec_model->hit($hit)){
                                        $error = $this->users_exec_model->getError();
                                        log_message("error","(next) No se pudo registrar hit users_id=[$uid], 
                                                                            object_id=[$hit->objects_id], 
                                                                            type_objects_id=[$hit->type_objects_id]. 
                                                                            Detalle=[$error]");
                                    }
                                }
                            }
                        }
                    }
                    else{
                        $res = array(
                            "success" => false,
                            "errors"=> array("Respuesta segundo termino [$answerId] de la pregunta [$question->id] no existe"),
                        );
                        $this->layout->printLike(json_encode($res), "json");
                        return;
                    }
                }
                else{
                    $res = array(
                        "success" => false,
                        "errors"=> array("Respuesta segundo termino seleccionada [$answerInnerId] de la pregunta [$question->id] no existe"),
                    );
                    $this->layout->printLike(json_encode($res), "json");
                    return;
                }
            }
            else{
                //verdadero o falso
                if($question->type_questions_id == $cfg->type_question_truefalse){
                    //hit de pregunta respondida
                    $hit->users_id = $uid;
                    $hit->objects_id = $current->id;
                    $hit->type_objects_id = $cfg->type_object_question;
                    $hit->status = "OK";
                    $hit->objectversion = $configObject->version;
                    $hit->execdetail = json_encode(array("selected"=>$answerId,"right"=>$current->value));
                    //aqui answerid tiene un valor 0|1 dependiendo de lo seleccionado como V|F
                    if($answerId != $current->value){
                        $hit->status = "EXEC";
                        $correct = false;
                    }
                    if(!$this->users_exec_model->hit($hit)){
                        $error = $this->users_exec_model->getError();
                        log_message("error","(next) No se pudo registrar hit users_id=[$uid], 
                                                            object_id=[$hit->objects_id], 
                                                            type_objects_id=[$hit->type_objects_id]. 
                                                            Detalle=[$error]");
                    }

                    $hitStatus = $hit->status ;
                }

            }
        }
        

        $finished = false;
        //validamos si fue la ultima pregunta del test, para cambiar el estado

        

        //si es tema consultamosd por la ultima pregunta configurada en module_object config
        if($configObject->type_objects_id == $cfg->type_object_theme){
            $index = count($lastTest->execdetail->questions);
            if($qCurrentId == $lastTest->execdetail->questions[$index-1]){
                //validamos si lo configurado de minCorrectanswers == a las OK de la prueba

                //obtenemos todo lo respondido para este test
                 //<-- se debe obtener este valor de los historicos
                $query = new stdClass();
                $query->objects = $lastTest->execdetail->questions;
                $query->users_id = $uid;
                $query->type_objects_id = $cfg->type_object_question;
                $query->dcreated = $lastTest->dcreated;
                $query->objectversion = $configObject->version;
                $answeredQuestions = $this->users_exec_model->getExecutedObjects($query);
                $filter = array();
                foreach ($answeredQuestions as $answer) {
                    if($answer->status == "OK")
                        $filter[$answer->objects_id] = $answer;
                }
                $okAnswers = count($filter);
                
                $testConfig = json_decode($configObject->config);
                $testConfig = $testConfig->test;
                //si lo contestado cumple con el minimo configurado para la prueba
                if($testConfig->minCorrectAnswers == $okAnswers){
                    $upd = new stdClass();
                    $upd->id = $lastTest->id;
                    $upd->status = $cfg->object_user_approved;//aprobo la prueba
                    $upd->dmodified = date('Y-m-d- H:i:s');
                    $finished = true;
                    if(!$this->users_exec_model->updateHit($upd)){
                        $error = $this->users_exec_model->getError();
                        log_message("error","(next) No se pudo actualizar hit de prueba, id=[$lastTest->id], 
                                                    status=[OK], Detalle=[$error]");
                    }
                }
                else{
                    //dejamos todas las preguntas que haya respondido como OK con estado OK_NULL
                    $upd = new stdClass();
                    $upd->users_id = $uid;
                    $upd->type_objects_id = $cfg->type_object_question;
                    $upd->dcreated = $lastTest->dcreated;
                    $upd->dmodified = date('Y-m-d H:i:s');
                    $upd->selected = implode(",", $lastTest->execdetail->questions);
                    $upd->status = "OK_NULL";
                    $this->users_exec_model->setOK2NullQuestions($upd);

                    //actualizamos configuracion de preguntas en hit de test con nuevas preguntas random
                    $selecteds = array();
                    $configQuestions = array();
                    $newQuestions = $this->_modelInstance->getByelem_test_id($elem_test_id);
                    shuffle($newQuestions);
                    for($i=0;$i<$testConfig->nQuestions; $i++){
                        $selecteds[] = $newQuestions[$i];
                        $configQuestions[] = $newQuestions[$i]->id;
                    }

                    $lastTest->repetitions++;
                    $upd = new stdClass();
                    $upd->id = $lastTest->id;
                    $upd->dmodified = date('Y-m-d H:i:s');
                    $upd->repetitions = $lastTest->repetitions;
                    $upd->execdetail = htmlspecialchars(json_encode(array("questions"=>$configQuestions)));

                    //actualizamosd hit de prueba
                    if(!$this->users_exec_model->updateHit($upd)){
                        $error = $this->users_exec_model->getError();
                        log_message("error","(reply) No se pudo actualizar hit [$lastTest->id] Detalle=[$error]");
                    }
                    

                    //la cantidad de repeticiones es igual al limite?
                    if($lastTest->repetitions >   $testConfig->repetitions){
                        $disableTest = true;
                        $reset = true;
                    }
                    
                    $newFirstQuestion = $selecteds[0];

                    //para el caso que sea un reply de terminos pareados
                    //incluimos reseteo de prueba solo si ha contestato todas las respuestas
                    if($question->type_questions_id == $cfg->type_question_pairterms){
                        $nanswers = 0;
                        foreach ($question->answers as $answer) {
                            if($answer->parent == "0"){
                                $nanswers++;
                            }
                        }
                        if(count($_pairTermsAnswers) != $nanswers){
                            $newFirstQuestion = null;
                        }
                    }


                }
            }
        }
        else{
            //si es caso clinico
            if($configObject->type_objects_id == $cfg->type_object_cliniccase){
                //vemos si la respuesta seleccionada tiene hijos
                $options = new stdClass();
                $options->type_object_parent_id = $cfg->type_object_answer;
                $options->parent = $answerId;
                $questions = $this->_modelInstance->getInnerQuestionsByParent($options);
                //si no posee mas preguntas llegamos a una hoja del arbol, por ende finaliza la prueba
                if(count($questions)==0){
                    $upd = new stdClass();
                    $upd->id = $lastTest->id;
                    $upd->status = $cfg->object_user_approved;//aprobo la prueba
                    $upd->dmodified = date('Y-m-d H:i:s');
                    $finished = true;
                    if(!$this->users_exec_model->updateHit($upd)){
                        $error = $this->users_exec_model->getError();
                        log_message("error","(next) No se pudo actualizar hit de prueba, id=[$lastTest->id], 
                                                    status=[OK], Detalle=[$error]");
                    }
                }
            }
        }
     
        //actualizamos estado del objeto X
        $upd = new stdClass();
        $upd->id = $lastExec->id;
        $upd->status = $cfg->object_user_exec;

        if($finished){
            $upd->status = $cfg->object_user_finished;//finalizo pero aun no se APRUEBA por admin
        }   
        if(!$this->users_exec_model->updateHit($upd)){
            log_message("error","(next) No se pudo actualizar hit de prueba, id=[$lastTest->id], 
                                        status=[OK], Detalle=[$error]");
        }
       

        $report = array();

        if($question->type_questions_id == $cfg->type_question_selection){
            //reporte de opciones respondidas
            $conditions = new stdClass();
            $conditions->users_id = $uid;
            $conditions->objects_id = $current->id;
            $conditions->objectversion = $configObject->version;
            $conditions->type_objects_id = $cfg->type_object_question;
            $report = $this->users_exec_model->reportAnswerPie($conditions);
        }
        
        if(!empty($newFirstQuestion)){
            $newFirstQuestion->answers = $this->elem_questions_answers_model->getByelem_questions_id($newFirstQuestion->id);
            if($newFirstQuestion->type_questions_id == $cfg->type_question_pairterms){
                $newFirstQuestion = $this->elem_questions_answers_model->getInnerAnswersFormat($newFirstQuestion);
            }
            
            $newFirstQuestion->description = html_entity_decode($newFirstQuestion->description);
        }
        


        $res = array(
            "success" => true,
            "data"=>array(
                'correct'=>$correct, //es correcta la respuesta?
                "reset"=>$reset,    //debe resetearse usando $newFirstQuestion
                'finished'=>$finished,  //finalizo?
                "newFirstQuestion"=>$newFirstQuestion //pregunta con la que se debe iniciar la prueba
            ),
            "report" => $report
        );
        $this->layout->printLike(json_encode($res), "json");
    }
}